#ifndef _SVC_THREAD_H_
#define _SVC_THREAD_H_

#ifdef __cplusplus
extern "C"
{
#endif

#include <types.h>
#include <semaphore.h>
#include <pthread.h>

#define SVC_ONCE_INIT       PTHREAD_ONCE_INIT

typedef pthread_once_t      svc_once_t;
typedef pthread_barrier_t   svc_barrier_t;
typedef pthread_t           svc_thread_t;
typedef pthread_mutex_t     svc_mutex_t;
typedef pthread_rwlock_t    svc_rwlock_t;
typedef sem_t               svc_sem_t;
typedef pthread_cond_t      svc_cond_t;
typedef pthread_key_t       svc_key_t;


int svc_barrier_init(svc_barrier_t *barrier, unsigned int count);
int svc_barrier_wait(svc_barrier_t *barrier);
void svc_barrier_destroy(svc_barrier_t *barrier);

int svc_thread_create_complex(svc_thread_t *tid, u32 stack_size,
                              void (*entry)(void *arg), void *arg);
int svc_thread_create(svc_thread_t *tid, void (*entry)(void *arg), void *arg);
svc_thread_t svc_thread_self(void);
int svc_thread_join(svc_thread_t *tid);
int svc_thread_equal(const svc_thread_t *t1, const svc_thread_t *t2);


int svc_mutex_init(svc_mutex_t *mutex);
int svc_mutex_init_recursive(svc_mutex_t *mutex);
void svc_mutex_destroy(svc_mutex_t *mutex);
void svc_mutex_lock(svc_mutex_t *mutex);
int svc_mutex_trylock(svc_mutex_t *mutex);
void svc_mutex_unlock(svc_mutex_t *mutex);


int svc_rwlock_init(svc_rwlock_t *rwlock);
void svc_rwlock_destroy(svc_rwlock_t *rwlock);
void svc_rwlock_rdlock(svc_rwlock_t *rwlock);
int svc_rwlock_tryrdlock(svc_rwlock_t *rwlock);
void svc_rwlock_rdunlock(svc_rwlock_t *rwlock);
void svc_rwlock_wrlock(svc_rwlock_t *rwlock);
int svc_rwlock_trywrlock(svc_rwlock_t *rwlock);
void svc_rwlock_wrunlock(svc_rwlock_t *rwlock);


void svc_once(svc_once_t *guard, void (*callback)(void));
int svc_sem_init(svc_sem_t *sem, unsigned int value);
void svc_sem_destroy(svc_sem_t *sem);
void svc_sem_post(svc_sem_t *sem);
void svc_sem_wait(svc_sem_t *sem);
int svc_sem_trywait(svc_sem_t *sem);


int svc_cond_init(svc_cond_t *cond);
void svc_cond_destroy(svc_cond_t *cond);
void svc_cond_signal(svc_cond_t *cond);
void svc_cond_broadcast(svc_cond_t *cond);
void svc_cond_wait(svc_cond_t *cond, svc_mutex_t *mutex);
int svc_cond_timedwait(svc_cond_t *cond, svc_mutex_t *mutex, u32 timeout);


int svc_key_create(svc_key_t *key);
void svc_key_delete(svc_key_t *key);
void *svc_key_get(svc_key_t *key);
void svc_key_set(svc_key_t *key, void *value);


void svc_sleep(unsigned int usec);
int system_run(const char *cmd, ...);

#ifdef __cplusplus
}
#endif
#endif
